﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using StedySoft.SenseSDK;
using StedySoft.SenseSDK.DrawingCE;

namespace Porter
{
    public partial class CtlFavorites : UserControl
    {
        private int _childLevel = -1;
        private string searchFilter;

        public CtlFavorites()
        {
            InitializeComponent();
            this.listFavorites = new SenseListControl()
            {
                Dock = System.Windows.Forms.DockStyle.Fill,
                FocusedItem = null,
                IsSecondaryScrollType = false,
                MinimumMovement = 15,
                Name = "listFavorites",
                ShowScrollIndicator = true,
                Height = this.Height,
                Springback = 0.35F,
                TabIndex = 1,
                ThreadSleep = 100,
                TopIndex = 0,
                Velocity = 0.9F
            };
            listFavorites.OnBeforeShowItemChildren += new SenseListControl.BeforeShowItemChildrenHandler(listFavorites_OnBeforeShowItemChildren);
            listFavorites.OnShowItemChildren += new SenseListControl.ShowItemChildrenHandler(listFavorites_OnShowItemChildren);
            listFavorites.OnHideItemChildren += new SenseListControl.HideItemChildrenHandler(listFavorites_OnHideItemChildren);
            this.Populate();
        }

        public void Populate()
        {
            try
            {
                /* Showing the list of favorite routes and lines */
                listFavorites.BeginUpdate();
                listFavorites.Clear();

                listFavorites.AddItem(new SensePanelDividerItem("lbMyRoutes", "My routes"));
                listFavorites.AddItem(new SensePanelMoreItem()
                {
                    Name = "AddRoute",
                    PrimaryText = "Add new route",
                    SecondaryText = String.Format("to other {0} favorites", Global.Favorites.Store.Routes.Count),
                    Enabled = true,
                    ProcessEntireButton = true
                });

                foreach (FavoriteStore.Route r in Global.Favorites.Store.Routes)
                {
                    string sLineList = "Lines: ";
                    foreach (FavoriteStore.Segment s in r.Segments)
                    {
                        sLineList += s.lnName + " ";
                    }
                    SensePanelMoreItem rItem = new SensePanelMoreItem()
                    {
                        Name = String.Format("route_{0}", r.Name),
                        PrimaryText = r.Name,
                        SecondaryText = sLineList,
                        Enabled = true,
                        ProcessEntireButton = false
                    };

                    rItem.OnClick += new SensePanelMoreItem.ClickEventHandler(rItem_OnClick);
                }

                listFavorites.AddItem(new SensePanelDividerItem("lbMyLines", "My lines"));
                listFavorites.AddItem(new SensePanelMoreItem()
                {
                    Name = "AddLine",
                    PrimaryText = "Add new line",
                    SecondaryText = String.Format("to other {0} favorites", Global.Favorites.Store.Lines.Count),
                    Enabled = true,
                    ProcessEntireButton = true
                });
                foreach (Service.Line r in Global.Favorites.Store.Lines)
                {
                    this.listFavorites.AddItem(new SensePanelMoreItem()
                    {
                        Name = String.Format("line_{0}", r.lnId),
                        PrimaryText = r.lnNumber,
                        SecondaryText = String.Format("{0} - {1}", r.endName1, r.endName2),
                        Enabled = true,
                        ProcessEntireButton = true
                    });
                }

                listFavorites.AddItem(new SensePanelDividerItem("lbMyPlaces", "My places"));
                listFavorites.AddItem(new SensePanelMoreItem()
                {
                    Name = "AddArea",
                    PrimaryText = "Add new area",
                    SecondaryText = String.Format("to other {0} favorites", Global.Favorites.Store.Areas.Count),
                    Enabled = true,
                    ProcessEntireButton = true
                });
                foreach (Map.GeoArea r in Global.Favorites.Store.Areas)
                {
                    SensePanelMoreItem aItem = new SensePanelMoreItem()
                    {
                        Name = String.Format("area_{0}", r.Name),
                        PrimaryText = r.Name,
                        Enabled = true
                    };
                
                    listFavorites.AddItem(aItem);
                }
                
                listFavorites.EndUpdate();
                this.Controls.Add(this.listFavorites);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void rItem_OnClick(object Sender)
        {

        }

        void listFavorites_OnBeforeShowItemChildren(SenseListControl.ISenseListItem Sender, ref bool Cancel)
        {
            SensePanelMoreItem itmMore = Sender as SensePanelMoreItem;
            if (itmMore.Children.Count > 0) itmMore.Children.Clear();
            if (Sender.Name.StartsWith("line_"))
            {
                int currentId = Int32.Parse(itmMore.Name.Substring(5));
                Service.LineInfo li = Global.m_service.Request(Service.Function.LineInfo, new Service.Parameters()
                {
                    lnId = new List<int>() { currentId }
                }).LineInfo;

                Service.Line l = Global.m_service.ResponseCache[Service.Function.Lines].Response.Lines.Line.First(line => line.lnId == currentId);

                itmMore.Children.Add(new SensePanelItem()
                {
                    Name = "CoName",
                    PrimaryText = l.lnNumber,
                    SecondaryText = l.coName
                });
                string dep = "Departures:\n";
                foreach (DateTime dt in li.GetDepartures(10)) dep += dt.ToShortTimeString() + " ";
                itmMore.Children.Add(new SensePanelTextboxItem()
                {
                    Name = "Departures",
                    Height = 300,
                    ReadOnly = true,
                    Text = dep,
                    Multiline = true
                });
                foreach(Service.StationDetail st in li.Stations)
                {
                    itmMore.Children.Add(new SensePanelItem()
                    {
                        Name = String.Format("st_{0}", st.stId),
                        PrimaryText = st.stName,
                        SecondaryText = String.Format("{0,-30}{1}", st.slRoute, st.slTime)
                    });
                }
            }
            if (Sender.Name.StartsWith("area_"))
            {
                SensePanelItem itemShow = new SensePanelItem()
                {
                    Name = String.Format("show_{0}", Sender.Name),
                    PrimaryText = String.Format("Show {0} on map", Sender.Name.Substring(5))
                };
                itemShow.OnClick += delegate(object s) {
                    try
                    {
                        Map.GeoArea r = Global.Favorites.Store.Areas.First(a => a.Name == Sender.Name.Substring(5));
                        Global.map.Fit(Global.map.MaxZoom, new List<Map.GeoPoint>()
                        {
                            r.UpperLeft,
                            r.LowerRight
                        });
                    }
                    catch (Exception)
                    {
                        MessageBox.Show("Tried to show invalid area!");
                    }
                };
                itmMore.Children.Add(itemShow);
                SensePanelItem itemDel = new SensePanelItem()
                {
                    Name = String.Format("del_{0}", Sender.Name),
                    PrimaryText = String.Format("Delete {0}", Sender.Name.Substring(5)),
                    IThumbnail = Graphics.Icon.Exit
                };
                itemDel.OnClick += delegate(object s) {
                    Map.GeoArea r = Global.Favorites.Store.Areas.First(a => a.Name == Sender.Name.Substring(5));
                    if (SenseAPIs.SenseMessageBox.Show(String.Format("Are you sure you want to remove {0} from favorite areas?", r.Name), 
                                                       "Delete favorite area?",
                                                       SenseMessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        Global.Favorites.Store.Areas.Remove(r);
                        Global.Favorites.Save();
                        this.Populate();
                    }
                };
                itmMore.Children.Add(itemDel);
            }
            switch (Sender.Name)
            {
                case "AddArea":
                    itmMore.Children.Add(new SensePanelDividerItem("ItemHeader", "Add new area"));
                    itmMore.Children.Add(new SensePanelTextboxItem()
                    {
                        Name = "ItemName",
                        LabelText = "Name: ",
                        Text = String.Format("Favorite place {0}", Global.Favorites.Store.Areas.Count + 1)
                    });
                    itmMore.Children.Add(new SensePanelDividerItem("ItemsTopLeftCorner", "Top left corner"));
                    itmMore.Children.Add(new SensePanelTextboxItem()
                    {
                        Name = "ItemTopLatitude",
                        LabelText = "Latitude: ",
                        Text = Global.map.TopLeftCorner.Latitude.ToString()
                    });
                    itmMore.Children.Add(new SensePanelTextboxItem()
                    {
                        Name = "ItemTopLongitude",
                        LabelText = "Longitude: ",
                        Text = Global.map.TopLeftCorner.Longitude.ToString()
                    });
                    itmMore.Children.Add(new SensePanelDividerItem("ItemsBottomRightCorner", "Bottom right corner"));
                    itmMore.Children.Add(new SensePanelTextboxItem()
                    {
                        Name = "ItemBottomLatitude",
                        LabelText = "Latitude: ",
                        Text = Global.map.BottomRightCorner.Latitude.ToString()
                    });
                    itmMore.Children.Add(new SensePanelTextboxItem()
                    {
                        Name = "ItemBottomLongitude",
                        LabelText = "Longitude: ",
                        Text = Global.map.BottomRightCorner.Longitude.ToString()
                    });

                    //TODO: add option for area resoultion (eg. every 2nd zoom level)

                    SensePanelButtonItem okButton = new SensePanelButtonItem()
                    {
                        Name = "OK",
                        Text = "Add to favorite areas"
                    };
                    okButton.OnClick += delegate(object s) {
                        try
                        {
                            Map.GeoArea newArea = new Map.GeoArea(
                                Double.Parse((itmMore.Children[3] as SensePanelTextboxItem).Text),
                                Double.Parse((itmMore.Children[4] as SensePanelTextboxItem).Text),
                                Double.Parse((itmMore.Children[6] as SensePanelTextboxItem).Text),
                                Double.Parse((itmMore.Children[7] as SensePanelTextboxItem).Text)
                            );
                            newArea.Name = (itmMore.Children[1] as SensePanelTextboxItem).Text;
                            Global.Favorites.Store.Areas.Add(newArea);
                            Global.Favorites.Save();
                            //TODO:    Global.map.Store(newArea);
                            // roll back to previous level
                            this.listFavorites.ShowParent();
                            this.Populate();
                        }
                        catch (Exception)
                        {
                            MessageBox.Show("Invalid area!");
                        }
                    };
                    itmMore.Children.Add(okButton);
                    break;
                case "AddLine":
                    itmMore.Children.Add(new SensePanelDividerItem("ItemHeader", "Add new line"));
                    SensePanelTextboxItem searchBox = new SensePanelTextboxItem()
                    {
                        Name = "SearchString",
                        LabelText = "Search: "
                    };
                    searchBox.TextChanged += delegate(object s, EventArgs e) { searchFilter = (s as SensePanelTextboxItem).Text; };
                    itmMore.Children.Add(searchBox);
                    itmMore.Children.Add(new SensePanelMoreItem()
                    {
                        Name = "SearchLine",
                        PrimaryText = "Search",
                        Enabled = true,
                        ProcessEntireButton = true
                    });

                    break;
                case "SearchLine":
                    itmMore.Children.RemoveAll(i => i.Name.StartsWith("line_"));
                    Service.Response r = Global.m_service.Request(Service.Function.Lines, new Service.Parameters());
                    if (r.code > 0)
                    {   // TODO: ékezetlevágós keresést csinálni (cserekarakterek)
                        foreach (Service.Line l in r.Lines.Line.Where(l => l.lnNumber.ToLower().Contains(searchFilter.ToLower()) ||
                                                                           l.endName1.ToLower().Contains(searchFilter.ToLower()) ||
                                                                           l.endName2.ToLower().Contains(searchFilter.ToLower())))
                        {
                            if (itmMore.Children.Count < Int32.Parse(Global.Settings.Get("MaxResults").ToString()))
                            {
                                SensePanelItem lItem = new SensePanelItem()
                                {
                                    Name = String.Format("line_{0}", l.lnId),
                                    PrimaryText = l.lnNumber,
                                    SecondaryText = String.Format("{0} - {1}", l.endName1, l.endName2)
                                };
                                lItem.OnClick += delegate(object sndr)
                                {
                                    if (SenseAPIs.SenseMessageBox.Show(String.Format("Are you sure you want to add line {0} to favorite lines?", l.lnNumber),
                                                                       "Add favorite line",
                                                                       SenseMessageBoxButtons.YesNo) == DialogResult.Yes)
                                    {
                                        Global.Favorites.Store.Lines.Add(l);
                                        Global.Favorites.Save();
                                        Global.m_service.Request(Service.Function.LineInfo, new Service.Parameters()
                                        {
                                            lnId = new List<int>() { l.lnId }
                                        });
                                        MessageBox.Show(String.Format("Line {0} successfully added to favorites.", l.lnNumber));
                                        this.Populate();
                                    }
                                };
                                itmMore.Children.Add(lItem);
                            }
                            else
                            {
                                MessageBox.Show("The number of results exceeds the defined maximum. Increase the limit or add more filter.");
                                break;
                            }
                        }
                    }
                    break;
            }
        }

        void listFavorites_OnShowItemChildren(SenseListControl.ISenseListItem Sender)
        {
            this._childLevel++;
        }

        void listFavorites_OnHideItemChildren(SenseListControl.ISenseListItem Sender)
        {
            this._childLevel--;
        }

        void Clear()
        {
            if (this.listFavorites != null)
            {
                this.listFavorites.Clear();
            }
        }
    }
}
